<html>
<head>
<meta charset="utf-8" />
<title>Java 程序中的多线程</title>
<style>
body {font-size: 0.75em;}
</style>
<script src="jquery-1.8.2.min.js"></script>
<script src="table-of-content-creator.js"></script>
</head>
<body>

<h1>Java 程序中的多线程</h1>
<p>在 Java 程序中使用多线程要比在 C 或 C++ 中容易得多，这是因为 Java 编程语言提供了语言级的支持。本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观。读完本文以后，用户应该能够编写简单的多线程程序。</p>

<h2>为什么会排队等待？</h2>
<p>下面的这个简单的 Java 程序完成四项不相关的任务。这样的程序有单个控制线程，控制在这四个任务之间线性地移动。此外，因为所需的资源 ― 打印机、磁盘、数据库和显示屏 -- 由于硬件和软件的限制都有内在的潜伏时间，所以每项任务都包含明显的等待时间。因此，程序在访问数据库之前必须等待打印机完成打印文件的任务，等等。如果您正在等待程序的完成，则这是对计算资源和您的时间的一种拙劣使用。改进此程序的一种方法是使它成为多线程的。</p>

<h2>使用 Java 编程语言实现线程</h2>

<p>Java 编程语言使多线程如此简单有效，以致于某些程序员说它实际上是自然的。尽管在 Java 中使用线程比在其他语言中要容易得多，仍然有一些概念需要掌握。要记住的一件重要的事情是 main() 函数也是一个线程，并可用来做有用的工作。程序员只有在需要多个线程时才需要创建新的线程。</p>

<h3>Thread 类</h3>
<p>Thread 类是一个具体的类，即不是抽象类，该类封装了线程的行为。要创建一个线程，程序员必须创建一个从 Thread 类导出的新类。程序员必须覆盖 Thread 的 run() 函数来完成有用的工作。用户并不直接调用此函数；而是必须调用 Thread 的 start() 函数，该函数再调用 run()。下面的代码说明了它的用法：</p>

<h3>Runnable 接口</h3>
<p>此接口只有一个函数，run()，此函数必须由实现了此接口的类实现。但是，就运行这个类而论，其语义与前一个示例稍有不同。我们可以用 runnable 接口改写前一个示例。（不同的部分用黑体表示。）</p>

<h3>synchronized 关键字</h3>
<p>到目前为止，我们看到的示例都只是以非常简单的方式来利用线程。只有最小的数据流，而且不会出现两个线程访问同一个对象的情况。但是，在大多数有用的程序中，线程之间通常有信息流。试考虑一个金融应用程序，它有一个 Account 对象，如下例中所示：</p>

<h2>Java 编程语言中的高级多线程支持</h2>

<p><strong>线程组 </strong><br/>
线程是被个别创建的，但可以将它们归类到 线程组中，以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中，使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。</p>
<p><strong>线程间发信 </strong><br/>
当线程在继续执行前需要等待一个条件时，仅有 synchronized 关键字是不够的。虽然 synchronized 关键字阻止并发更新一个对象，但它没有实现 线程间发信 。Object 类为此提供了三个函数：wait()、notify() 和 notifyAll()。以全球气候预测程序为例。这些程序通过将地球分为许多单元，在每个循环中，每个单元的计算都是隔离进行的，直到这些值趋于稳定，然后相邻单元之间就会交换一些数据。所以，从本质上讲，在每个循环中各个线程都必须等待所有线程完成各自的任务以后才能进入下一个循环。这个模型称为 屏蔽同步，下例说明了这个模型：</p>

<h2>避免不提倡使用的方法</h2>

<p>不提倡使用的方法是为支持向后兼容性而保留的那些方法，它们在以后的版本中可能出现，也可能不出现。Java 多线程支持在版本 1.1 和版本 1.2 中做了重大修订，stop()、suspend() 和 resume() 函数已不提倡使用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听起来很诱人，但请抵制诱惑不要使用它们。</p>

</body>
</html>